package com.zhangxx.inventory.thread.threadpool;

import com.zhangxx.inventory.constant.Constants;
import com.zhangxx.inventory.thread.request.Request;
import com.zhangxx.inventory.thread.request.RequestQueue;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @ClassName ProcessThreadPool
 * @Description 线程池
 * @Author leizhang
 * Date 2022/3/18 13:31
 * @Version 1.0
 **/
public class ProcessThreadPool {
    /**
     * @Description :核心线程数（默认线程数）
     **/
    private static final int corePoolSize = Runtime.getRuntime().availableProcessors();
    /**
     * @Description : 最大线程数
     **/
    private static final int maxPoolSize = corePoolSize * 2;
    /**
     * @Description :允许线程空闲时间（单位：默认为秒）
     **/
    private static final int keepAliveTime = 10;
    /**
     * @Description :缓冲队列数
     **/
    private static final int queueCapacity = 50;
    /**
     * @Description :线程池名前缀
     **/
    private static final String threadNamePrefix = "default-async-";

    public ThreadPoolTaskExecutor initTaskExecutor(){
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setThreadNamePrefix(threadNamePrefix+"ProductInventCache");
        pool.setCorePoolSize(corePoolSize);
        pool.setMaxPoolSize(maxPoolSize);
        pool.setKeepAliveSeconds(keepAliveTime);
        pool.setQueueCapacity(queueCapacity);
        // 直接在execute方法的调用线程中运行
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化
        pool.initialize();
        return pool;
    }

    private ProcessThreadPool(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = initTaskExecutor();
        //维护十个队列
        RequestQueue requestQueue = RequestQueue.getInstance();
        for(int i=Constants.ZERO; i< Constants.TEN; i++){
            ArrayBlockingQueue<Request> queue = new ArrayBlockingQueue<>(Constants.HUNDRED);
            requestQueue.addQueue(queue);
            threadPoolTaskExecutor.submit(new RequestProcessThread(queue));
        }
    }

    /**单例创建对象**/
    private static class SingletonPool{
        private static volatile ProcessThreadPool instance;

        private static ProcessThreadPool getInstance() {
             if (null == instance) {
                 synchronized (ProcessThreadPool.class){
                     if (null == instance) {
                         instance = new ProcessThreadPool();
                     }
                 }
             }
             return instance;
        }
    }
    public static ProcessThreadPool getInstance(){
        return SingletonPool.getInstance();
    }

    public static  ProcessThreadPool initPool(){
        return getInstance();
    }

}
